package imp

import (
	sqlc "bgs/db/sqlc"
	storeFollowGrpc "bgs/grpc/gen/service/store_follow"
	"bgs/grpc/gen/shared/message"
	"context"
)

/****************************************************************************************/
/*                               store_follow entity of helper                           */
/****************************************************************************************/

func transformStoreFollowEntityToPb(StoreFollow sqlc.StoreFollow) *storeFollowGrpc.StoreFollowEntity {
	return &storeFollowGrpc.StoreFollowEntity{
		Id:              StoreFollow.ID,
		UserId:          StoreFollow.UserID,
		FollowedStoreId: StoreFollow.FollowedStoreID,
		Followed:        sqlc.GoTimeToPBTimestamp(StoreFollow.Followed),
		Remark:          StoreFollow.Remark.String,
	}
}

/****************************************************************************************/
/*                               store_follow entity of cmd                              */
/****************************************************************************************/

// UpsertStoreFollow 创建用户关注关系
func (s *StoreAPIService) UpsertStoreFollow(ctx context.Context, req *storeFollowGrpc.UpsertStoreFollowRequest) (res *storeFollowGrpc.UpsertStoreFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_followImp->UpsertStoreFollow:%v", req)
	res = &storeFollowGrpc.UpsertStoreFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpsertStoreFollowParams{
		UserID:          req.UserId,
		FollowedStoreID: req.FollowedStoreId,
		Followed:        sqlc.PBTimestampToGoTime(req.Followed),
	}
	storeFollow, err := s.dao.Q.UpsertStoreFollow(ctx, arg)

	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.StoreFollow = transformStoreFollowEntityToPb(storeFollow)
	return
}

// UpdateStoreFollow 更新用户关注关系
func (s *StoreAPIService) UpdateStoreFollow(ctx context.Context, req *storeFollowGrpc.UpdateStoreFollowRequest) (res *storeFollowGrpc.UpdateStoreFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_followImp->UpdateStoreFollow:%v", req)
	res = &storeFollowGrpc.UpdateStoreFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpdateStoreFollowParams{
		ID:     req.Id,
		Remark: sqlc.NSFromString(req.Remark),
	}
	storeFollow, err := s.dao.Q.UpdateStoreFollow(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.StoreFollow = transformStoreFollowEntityToPb(storeFollow)
	return
}

/****************************************************************************************/
/*                               store_follow entity of query                            */
/****************************************************************************************/

// GetStoreFollow 获取单个用户关注
func (s *StoreAPIService) GetStoreFollow(ctx context.Context, req *storeFollowGrpc.GetStoreFollowRequest) (res *storeFollowGrpc.GetStoreFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_followImp->GetStoreFollow:%v", req)
	res = &storeFollowGrpc.GetStoreFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	storeFollow, err := s.dao.Q.GetStoreFollow(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.StoreFollow = transformStoreFollowEntityToPb(storeFollow)
	return
}

/****************************************************************************************/
/*                            store_followJoins entity of helper                            */
/****************************************************************************************/

func transformStoreFollowWithStoreAndStoreStatEntityToPb(row sqlc.ListStoreFollowWithStoreAndStoreStatsRow) *storeFollowGrpc.StoreFollowWithStoreAndStoreStatEntity {
	return &storeFollowGrpc.StoreFollowWithStoreAndStoreStatEntity{
		// store_follow
		Id:              row.ID,
		UserId:          row.UserID,
		FollowedStoreId: row.FollowedStoreID,
		Followed:        sqlc.GoTimeToPBTimestamp(row.Followed),
		Remark:          row.Remark.String,

		// store
		FollowedStoreName: row.Name,
		FollowedStorePic:  row.Pic,

		// store_stat
		FansCount:                  row.FansCount,
		PublishActivityCount:       row.PublishActivityCount,
		SpokesmanCount:             row.SpokesmanCount,
		EndorseRequestToAuditCount: row.EndorseRequestToAuditCount,
	}
}

func mapStoreFollowWithStoreAndStoreStatEntityToPb(list []sqlc.ListStoreFollowWithStoreAndStoreStatsRow, f func(sqlc.ListStoreFollowWithStoreAndStoreStatsRow) *storeFollowGrpc.StoreFollowWithStoreAndStoreStatEntity) []*storeFollowGrpc.StoreFollowWithStoreAndStoreStatEntity {
	r := make([]*storeFollowGrpc.StoreFollowWithStoreAndStoreStatEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                            store_followJoins entity of query                             */
/****************************************************************************************/

// ListStoreFollowWithStoreAndStoreStats  获取关注的用户及其统计信息
func (s *StoreAPIService) ListStoreFollowWithStoreAndStoreStats(ctx context.Context, req *storeFollowGrpc.ListStoreFollowWithStoreAndStoreStatsRequest) (res *storeFollowGrpc.ListStoreFollowWithStoreAndStoreStatsResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_followImp->ListStoreFollowWithStoreAndStoreStats:%v", req)

	res = &storeFollowGrpc.ListStoreFollowWithStoreAndStoreStatsResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	total, err := s.dao.Q.CountStoreFollowWithStoreAndStoreStats(ctx, req.UserId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	arg := sqlc.ListStoreFollowWithStoreAndStoreStatsParams{
		Limit:  req.Limit,
		Offset: req.Offset,
		UserID: req.UserId,
	}
	storeFollowWithStoreAndStoreStats, err := s.dao.Q.ListStoreFollowWithStoreAndStoreStats(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.StoreFollowWithStoreAndStoreStats = mapStoreFollowWithStoreAndStoreStatEntityToPb(storeFollowWithStoreAndStoreStats, transformStoreFollowWithStoreAndStoreStatEntityToPb)
	return
}
